<template>
  <transition name="list-fade">
    <div class="playlist" v-show="showFlag" @click="hide">
      <!-- 这里添加一个@click.stop 防止冒泡上去触发hide函数 -->
      <div class="list-wrapper" @click.stop>
        <div class="list-header">
          <h1 class="title">
            <i class="icon" :class="iconMode" @click="changeMode"></i>
            <span class="text">{{ modeText }}</span>
            <span class="clear" @click="showConfirm">
              <i class="iconfont icon-clear"></i>
            </span>
          </h1>
        </div>
        <scroll :refreshDelay="refreshDelay" :data="sequenceList" class="list-content" ref="listContent">
          <transition-group name="list" tag="ul">
            <li ref="listItem"
              class="item"
              v-for="(item, index) in sequenceList"
              :key="item.id"
              @click="selectItem(item, index)"
            >
              <i class="current" :class="getCurrentIcon(item)"></i>
              <span class="text">{{ item.name }}</span>
              <span @click.stop="toggleFavorite(item)" class="like">
                <i class="iconfont" :class="getFavoriteIcon(item)"></i>
              </span>
              <span class="delete" @click.stop="deleteOne(item)">
                <i class="iconfont icon-delete"></i>
              </span>
            </li>
          </transition-group>
        </scroll>
        <div class="list-operate">
          <div class="add" @click="addSong">
            <i class="icon-add"></i>
            <span class="text">添加歌曲到队列</span>
          </div>
        </div>
        <div class="list-close" @click="hide">
          <span>关闭</span>
        </div>
      </div>
      <confirm ref="confirm" @confirm="confirmClear" text="是否清空播放列表" confirmBtnText="清空" />
      <add-song ref="addSong" />
    </div>
  </transition>
</template>

<script>
import { mapActions } from 'vuex'
import { playMode } from '../../assets/js/config'
import Scroll from '../../base/scroll/Scroll'
import Confirm from '../../base/confirm/Confirm'
import AddSong from '../add-song/AddSong'
import { playerMixin } from '../../assets/js/mixin'

export default {
  name: 'PlayList',
  mixins: [playerMixin],
  data() {
    return {
      showFlag: false,
      refreshDelay: 106
    }
  },
  computed: {
    // ...mapGetters([
    //   'sequenceList',
    //   'currentSong',
    //   'playlist',
    //   'mode'
    // ])
    modeText() {
      return this.mode === playMode.sequence ? '顺序播放' : this.mode === playMode.random ? '随机播放' : '单曲循环'
    }
  },
  methods: {
    show() {
      this.showFlag = true
      // 因为playlist组件点击显示后是从display:none到显示, BScroll没能正确计算, 所以这里直接刷新
      setTimeout(() => {
        this.$refs.listContent.refresh()
        // 当playlist组件显示的时候, 播放的歌曲滚动到第一位的位置
        this.scrollToCurrent(this.currentSong)
      }, 20)
    },
    hide() {
      this.showFlag = false
    },
    getCurrentIcon(item) {
      if (this.currentSong.id === item.id) {
        return 'iconfont icon-play'
      }
      return ''
    },
    selectItem(item, index) {
      if (this.mode === playMode.random) {
        index = this.playlist.findIndex((song) => {
          return song.id === item.id
        })
      }
      this.setCurrentIndex(index)
      this.setPlayingState(true)
    },
    deleteOne(item) {
      this.deleteSong(item)
      // 我们删除歌曲应该会有状态的切换? 暂停时删除删除歌曲切换到播放状态, 但这个action动作应该放到deleteSong的action中
      // 这样这个方法就专注于delete song的逻辑
      // this.setPlayingState(true)

      if (!this.playlist.length) {
        this.hide()
      }
    },
    showConfirm() {
      this.$refs.confirm.show()
    },
    confirmClear() {
      this.deleteSongListAll()
      this.hide()
    },
    scrollToCurrent(current) {
      const index = this.sequenceList.findIndex((song) => {
        return current.id === song.id
      })
      this.$refs.listContent.scrollToElement(this.$refs.listItem[index], 300)
    },
    addSong() {
      this.$refs.addSong.show()
    },
    // ...mapMutations({
    //   setCurrentIndex: 'SET_CURRENT_INDEX',
    //   setPlayingState: 'SET_PLAYING_STATE'
    // }),
    ...mapActions([
      'deleteSong',
      'deleteSongListAll'
    ])
  },
  watch: {
    currentSong(newSong, oldSong) {
      // 监听currentSong的变化, 将playlist播放的歌曲滚动到第一位的位置
      if (!this.showFlag || newSong.id === oldSong.id) {
        return
      }
      this.scrollToCurrent(newSong)
    }
  },
  components: {
    Scroll,
    Confirm,
    AddSong
  }
}
</script>

<style lang="scss" scoped>
@import "../../assets/css/variable.scss";
@import "../../assets/css/mixin.scss";

.playlist{
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  z-index: 200;
  background-color: $color-background-d;
  &.list-fade-enter-active, &.list-fade-leave-active{
    transition: opacity 0.3s;
    .list-wrapper{
      transition: all 0.3s;
    }
  }
  &.list-fade-enter, &.list-fade-leave-to{
    opacity: 0;
    .list-wrapper{
      transform: translate3d(0, 100%, 0);
    }
  }
  .list-wrapper{
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    background-color: $color-highlight-background;
    .list-header{
      position: relative;
      padding: 20px 30px 10px 20px;
      .title{
        display: flex;
        align-items: center;
        .icon{
          margin-right: 10px;
          font-size: 30px;
          color: $color-theme-d;
        }
        .text{
          flex: 1;
          font-size: $font-size-medium;
          color: $color-text-l;
        }
        .clear{
          @include extend-click();
          .icon-clear{
            font-size: $font-size-medium-x;
            color: $color-text-d;
          }
        }
      }
    }
    .list-content{
      max-height: 240px;
      overflow: hidden;
      .item{
        display: flex;
        align-items: center;
        height: 40px;
        padding: 0 30px 0 20px;
        overflow: hidden;
        &.list-enter-active, &.list-leave-active{
          transition: all 0.1s linear;
        }
        &.list-enter, &.list-leave-to{
          height: 0;
        }
        .current{
          flex: 0 0 20px;
          width: 20px;
          font-size: $font-size-medium-x;
          color: $color-theme-d;
        }
        .text{
          flex: 1;
          @include no-wrap();
          font-size: $font-size-medium;
          color: $color-text-d;
        }
        .like{
          @include extend-click();
          margin-right: 15px;
          font-size: $font-size-small;
          color: $color-theme;
          .icon-favorite{
            color: $color-sub-theme;
          }
        }
        .delete{
          @include extend-click();
          font-size: $font-size-small;
          color: $color-theme;
        }
      }
    }
    .list-operate{
      width: 140px;
      margin: 20px auto 30px auto;
      .add{
        display: flex;
        align-items: center;
        padding: 8px 16px;
        border: 1px solid $color-text-l;
        border-radius: 100px;
        color: $color-text-l;
        .icon-add{
          margin-right: 5px;
          font-size: $font-size-small-s;
        }
        .text{
          font-size: $font-size-small;
        }
      }
    }
    .list-close{
      text-align: center;
      line-height: 50px;
      background: $color-background;
      font-size: $font-size-medium-x;
      color: $color-text-l;
    }
  }
}
</style>